﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Management.Automation;
using System.Management;

namespace HyperVSnapin.Helpers
{
    internal class GenericWMIHelper
    {
        /// <summary>
        /// Allow to query WMI
        /// </summary>
        /// <param name="wmiClass">The class on with query object</param>
        /// <param name="condition">Where clause for the query</param>
        /// <param name="host">Host if not current (local)</param>
        /// <param name="wmiNamespace">WMI namespace if not default (default should me root\cli. Sample: @"root\Virtualization")</param>
        public List<ManagementObject> Query(string wmiClass, string condition, string host, PSCredential credential, string wmiNamespace)
        {
            ConnectionOptions oConn = GetConnectionOptions(credential);
            ObjectQuery oQuery = new ObjectQuery(string.Format("SELECT * FROM {0} WHERE {1}", wmiClass, condition.Replace('*', '%').Replace('?', '_')));
            ManagementScope scope = GetScope(host, wmiNamespace, oConn);
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, oQuery);
            List<ManagementObject> list = new List<ManagementObject>();
            foreach (ManagementObject mo in searcher.Get())
            {
                list.Add(mo);
            }
            return list;
        }

        /// <summary>
        /// Invoke a method on a WMI object
        /// </summary>
        /// <param name="mo">WMI Object on which invoke the method</param>
        /// <param name="method">Name of the method to invoke</param>
        /// <param name="param">Parameters for the method (if any)</param>
        public void Invoke(System.Management.ManagementObject mo, string method, params object[] args)
        {
            mo.InvokeMethod(method, args);
        }

        private ManagementScope GetScope(string hostName, string wmiNamespace, ConnectionOptions oConn)
        {
            string query = string.Format(@"\\{0}\{1}", hostName, wmiNamespace);
            return new ManagementScope(query, oConn);
        }

        private ConnectionOptions GetConnectionOptions(PSCredential credential)
        {
            ConnectionOptions oConn = new ConnectionOptions();
            if (credential != null)
            {
                oConn.Username = credential.UserName;
                oConn.SecurePassword = credential.Password;
            }
            return oConn;
        }
    }
}
